﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebCommit.Common.Entitys;
using System.ComponentModel;

namespace WebCommit.Crawler
{
	public class CrawlerManager
	{
		#region constructor
		//private static CrawlerManager _Instance = null;
		private List<Worker> WorkerList = new List<Worker>();

		private object LockObj = new object();
		//public static CrawlerManager Current
		//{
		//    get
		//    {
		//        if (_Instance == null)
		//            _Instance = new CrawlerManager();

		//        return _Instance;
		//    }
		//}

		public CrawlerManager(List<WebResourceEntity> webList)
		{
			WebList = webList;
			CreateWorkers();
		}
		#endregion

		public delegate void OnStarted(object sender, WorkerEventArgs e);
		//public delegate void OnProgressChanged(object sender, WorkerEventArgs e);
		public delegate void OnStoped(object sender, WorkerEventArgs e);

		public event OnStarted Started;
		//public event OnProgressChanged ProgressChanged;
		public event OnStoped Stoped;

		/// <summary>
		/// WebResource列表
		/// </summary>
		public List<WebResourceEntity> WebList
		{
			get;
			set;
		}

		public HashSet<string> UrlHistory
		{
			get;
			set;
		}

		private bool _IsStoping = false;
		private bool _IsStoped = true;
		/// <summary>
		/// 停止
		/// </summary>
		public void Stop()
		{
			this._IsStoping = true;
			foreach (Worker worker in WorkerList)
			{
				worker.Stop();
			}
			if (Stoped != null)
			{
				Stoped.DynamicInvoke(this, new WorkerEventArgs() { UrlList = WebList });
			}

		}

		/// <summary>
		/// 开始
		/// </summary>
		public void Start()
		{
			_IsStoped = false;
			foreach (Worker worker in WorkerList)
			{
				worker.Start();
			}
			if (Started != null)
				Started.DynamicInvoke(this, new WorkerEventArgs() { UrlList = WebList });
		}

		private void CreateWorkers()
		{
			List<WorkerConfig> cfgList = (List<WorkerConfig>)System.Configuration.ConfigurationManager.GetSection("CrawlerWorkers");
			foreach (WorkerConfig cfg in cfgList)
			{
				for (int i = 0; i < cfg.Count; i++)
				{
					Worker w = (Worker)System.Activator.CreateInstance(cfg.WorkerType, WebList, LockObj);
					//w.ProgressChanged += new Worker.OnProgressChanged(w_ProgressChanged);
					w.Started += new Worker.OnStarted(w_Started);
					w.Stoped += new Worker.OnStoped(w_Stoped);
					WorkerList.Add(w);
				}
			}
			
		}

		void w_Stoped(object sender, WorkerEventArgs e)
		{
			if (Stoped != null && WorkerList.Count(w => w.CurrentStatus == WorkerStatus.Working) == 0)
			{
				Stoped.DynamicInvoke(this, new WorkerEventArgs() { UrlList = WebList });
			}
		}

		void w_Started(object sender, WorkerEventArgs e)
		{
			if (Started != null && WorkerList.Count(w => w.CurrentStatus == WorkerStatus.Stoped) == 0)
			{
				Started.DynamicInvoke(this, new WorkerEventArgs() { UrlList = WebList });
			}
		}

		//void w_ProgressChanged(object sender, WorkerEventArgs e)
		//{
		//    if (ProgressChanged != null)
		//        ProgressChanged.DynamicInvoke(this, new WorkerEventArgs() { UrlList = e.UrlList });

		//}

	}
}
